package cn.antcore.common.access;

import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;
import java.util.function.Supplier;

/**
 * OAuth2权限验证
 * <br>
 * Created by Hong 2024/5/29
 **/
public class OAuth2SecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

    private static final String defaultScopePrefix = "SCOPE_";

    private Object filterObject;
    private Object returnObject;
    private Object target;

    public OAuth2SecurityExpressionRoot(Authentication authentication) {
        super(authentication);
    }

    public OAuth2SecurityExpressionRoot(Supplier<Authentication> authentication) {
        super(authentication);
    }

    public boolean hasScope(String scope) {
        return getAuthentication().getAuthorities().stream().anyMatch(it -> it.getAuthority().equals(defaultScopePrefix + scope));
    }

    public boolean hasScope(String... scopes) {
        Collection<? extends GrantedAuthority> list = getAuthentication().getAuthorities();
        for (String scope : scopes) {
            if (list.stream().anyMatch(it -> it.getAuthority().equals(defaultScopePrefix + scope))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void setFilterObject(Object filterObject) {
        this.filterObject = filterObject;
    }

    @Override
    public Object getFilterObject() {
        return this.filterObject;
    }

    @Override
    public void setReturnObject(Object returnObject) {
        this.returnObject = returnObject;
    }

    @Override
    public Object getReturnObject() {
        return this.returnObject;
    }

    void setThis(Object target) {
        this.target = target;
    }


    @Override
    public Object getThis() {
        return this.target;
    }
}
